/*
 * @Author: 李超越 1509572300@qq.com
 * @Date: 2024-08-23 09:17:16
 * @LastEditors: 李超越 1509572300@qq.com
 * @LastEditTime: 2024-08-23 16:40:22
 * @FilePath: /my_git/lesson28_thread/mythread.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "thread.hpp"

using namespace ThreadModule;

int g_tickets=10000;
const int num=4;
//pthread_mutex_t gmutex=PTHREAD_MUTEX_INITIALIZER;


//c++11同样支持多线程，mutex
class ThreadData
{
public:
    ThreadData(int& tickets,const string& name,pthread_mutex_t& mutex)
        :_tickets(tickets),_name(name),_total(0),_mutex(mutex)
    {}


     
    ~ThreadData()
    {}

    int &_tickets;
    string _name;
    int _total;
    pthread_mutex_t &_mutex;
};

// void route(ThreadData* td)
// {
//     pthread_mutex_lock(&td->_mutex);
//     while(td->_tickets>0)
//     {
//         usleep(1000);
//         //pthread_mutex_lock(&gmutex);    
//         cout<<td->_name<<" running,get tickets:"<<td->_tickets<<endl;
//         td->_tickets--;
//         td->_total++;
//         //pthread_mutex_unlock(&gmutex);
//     }
//     pthread_mutex_unlock(&td->_mutex);
// }

void route(ThreadData* td)
{
    while(true)
    {
        LockGuard guard(&td->_mutex);
        if(td->_tickets>0)
        {
            usleep(1000);
            cout<<td->_name<<" running,get tickets:"<<td->_tickets<<endl;
            td->_tickets--;
            td->_total++;
        }
        else
        {
            break;
        }
    }
}



int main()
{
    //定义锁，初始化锁
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,nullptr);

    vector<Thread<ThreadData*>> threads;
    vector<ThreadData*> datas;
    for(int i=0;i<num;i++)
    {
        string name="Thread-"+to_string(i);
        ThreadData* td=new ThreadData(g_tickets,name,mutex);
        threads.emplace_back(route,td,name);
        datas.emplace_back(td);
    }

    //启动进程
    for(auto &thread:threads)
    {
        thread.Start();
    }

    //等待线程
    for(auto &thread: threads)
    {
        thread.Join();
        cout<<"wait thread done,thread is:"<<thread.name()<<endl;
    }

    //
    for(auto &data: datas)
    {
        cout<<data->_name<<":"<<data->_total<<endl;
        delete data;
    }

    //释放锁
    pthread_mutex_destroy(&mutex);
    return 0;
}